package com.yuandian.management.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuandian.api.business_monitor.po.SearchParams;
import com.yuandian.api.management.annotation.UpdateConfig;
import com.yuandian.api.management.entity.ConfBusiness;
import com.yuandian.api.management.entity.ConfSegment;
import com.yuandian.api.management.entity.ConfSystem;
import com.yuandian.bpm.admin.api.entity.SysDictItem;
import com.yuandian.bpm.admin.api.feign.RemoteDictService;
import com.yuandian.bpm.admin.api.feign.RemoteParamService;
import com.yuandian.bpm.common.core.util.R;
import com.yuandian.bpm.common.security.util.SecurityUtils;
import com.yuandian.constant.DictType;
import com.yuandian.enums.ResultCodeEnum;
import com.yuandian.management.mapper.ConfSystemMapper;
import com.yuandian.management.service.ConfBusinessService;
import com.yuandian.management.service.ConfSegmentService;
import com.yuandian.management.service.ConfSystemService;
import com.yuandian.management.vo.SearchOptionVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 系统配置表-Service实现
 * @author zfsn
 * @date 2023-3-7
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ConfSystemServiceImpl extends ServiceImpl<ConfSystemMapper, ConfSystem>
        implements ConfSystemService {

	@Autowired
	private final ConfSystemMapper confSystemMapper;

	@Autowired
	private final RemoteDictService remoteDictService;

	@Autowired
	private final ConfBusinessService confBusinessService;

	@Autowired
	private final ConfSegmentService confSegmentService;

	@Override
	public ConfSystem getById(Serializable id) {
		ConfSystem confSystem = super.getById(id);
		if (confSystem == null){
			return null;
		}
		Map<String, String> systemDomainMap = getDictMap(DictType.SYSTEM_DOMAIN);
		Map<String, String> cloudPlatformMap = getDictMap(DictType.CLOUD_PLATFORM);
		Map<String, String> systemTypeMap = getDictMap(DictType.SYSTEM_TYPE);
		confSystem.setSystemDomain(systemDomainMap.get(confSystem.getDomainCode()));
		confSystem.setSystemType(systemTypeMap.get(String.valueOf(confSystem.getType())));
		confSystem.setCloudPlatformName(cloudPlatformMap.get(String.valueOf(confSystem.getCloudPlatformCode())));
		return confSystem;
	}

	/**
	 *
	 * @param dictCode
	 * @return k:itemValue v:label
	 */
	private Map<String, String> getDictMap(String dictCode) {
		return remoteDictService.getDictByType(dictCode).getData()
				.stream().collect(Collectors.toMap(SysDictItem::getItemValue, SysDictItem::getLabel));
	}

	/**
	 * 分页查询
	 * @param confSystemParam
	 * @return
	 */
	@Override
	public Page<ConfSystem> listPage(ConfSystem confSystemParam) {
		Page<ConfSystem> confSystemPage = confSystemMapper.listPage(new Page<>(confSystemParam.getPageNum(), confSystemParam.getPageSize()), confSystemParam);
		Map<String, String> systemDomainMap = getDictMap(DictType.SYSTEM_DOMAIN);
		Map<String, String> cloudPlatformMap = getDictMap(DictType.CLOUD_PLATFORM);
		Map<String, String> systemTypeMap = getDictMap(DictType.SYSTEM_TYPE);
		for (ConfSystem confSystem : confSystemPage.getRecords()) {
			confSystem.setDomainName(systemDomainMap.get(confSystem.getDomainCode()));
			confSystem.setSystemType(systemTypeMap.get(String.valueOf(confSystem.getType())));
			confSystem.setCloudPlatformName(cloudPlatformMap.get(String.valueOf(confSystem.getCloudPlatformCode())));
		}
		return confSystemPage;
	}

	/**
	 * 通过主键删除数据
	 *
	 * 删除某个系统数据之前， 先删除改系统关联的网端、 业务、告警信息配置信息
	 *
	 * @param systemIds 主键
	 * @return 通用返回对象
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean removeByIds(List<Integer> systemIds) {
		QueryWrapper<ConfBusiness> businessQueryWrapper = new QueryWrapper<>();
		businessQueryWrapper.in("system_id", systemIds);
		QueryWrapper<ConfSegment> segmentQueryWrapper = new QueryWrapper<>();
		segmentQueryWrapper.in("system_id", systemIds);
		// 删除对应的告警信息
		log.warn("删除系统id为：{}的数据", systemIds);
		return confSegmentService.count(segmentQueryWrapper) == 0 && confBusinessService.count(businessQueryWrapper) == 0 && super.removeByIds(systemIds);
	}


	/**
	 * 重写保存方法
	 * @param confSystem 系统对象
	 * @return boolean
	 */
	@Override
	public R<String> saveSystem(ConfSystem confSystem) {
		// 特殊需求
		if(exceedMaxSystemConfigLimit()){
			log.error("添加系统数量超过可配置数量，请联系源典工作人员!");
			return R.failed("添加系统数量超过可配置数量，请联系源典工作人员!");
		}
		if (!checkSystemNameDuplicates(confSystem)) {
			confSystem.setCreateBy(SecurityUtils.getUser().getName());
			confSystem.setCreateTime(LocalDateTime.now());
			confSystem.setUpdateBy(SecurityUtils.getUser().getName());
			confSystem.setUpdateTime(LocalDateTime.now());
			confSystemMapper.insert(confSystem);
			return R.ok("添加系统成功");
		}
		log.warn("系统名称{}存在重复", confSystem.getName());
		return R.failed(ResultCodeEnum.SYSTEM_NAME_EXIST.getMsg());
	}

	/**
	 * 通过域code 获取该域下所有的系统
	 *
	 * @return 返回对象
	 */
	@Override
	public List<ConfSystem> getSystemsAndDomain() {
		List<ConfSystem> confSystems = super.list();
		Map<String, String> systemDomainMap = remoteDictService.getDictByType(DictType.SYSTEM_DOMAIN).getData().stream().collect(Collectors.toMap(SysDictItem::getItemValue, SysDictItem::getLabel));
		for (ConfSystem confSystem : confSystems) {
			confSystem.setDomainName(systemDomainMap.get(confSystem.getDomainCode()));
		}
		return confSystems;
	}

	/**
	 * 查询默认的应用系统选项列表
	 * @param params 搜索项请求参数
	 * @return 搜索选项vo对象集合
	 */
	@Override
	public List<SearchOptionVo> queryDefaultAppSystemOptions(SearchParams params) {
		return this.baseMapper.queryDefaultAppSystemOptions(params);
	}


	/**
	 * 重写更新方法
	 * @param confSystem
	 * @return
	 */
	@Override
	public boolean updateById(ConfSystem confSystem) {
		confSystem.setUpdateBy(SecurityUtils.getUser().getName());
		confSystem.setUpdateTime(LocalDateTime.now());
		if (!checkSystemNameDuplicates(confSystem)) {
			int affectCount = confSystemMapper.updateById(confSystem);

			return affectCount > 0;
		}
		return false;
	}

	/**
	 * 判断系统名称是否重复
	 * @param confSystem
	 */
	private boolean checkSystemNameDuplicates(ConfSystem confSystem) {
		return confSystemMapper.checkSystemNameDuplicates(confSystem) > 0;
	}

	/**
	 * 是否批量启动或者停用系统
	 *
	 * @param ids
	 * @param isStartSystem
	 * @return
	 */
	@Override
	@UpdateConfig
	public R<String> changeSystemStatus(List<Integer> ids, boolean isStartSystem) {
		log.info("修改系统{}的为{}状态", ids, isStartSystem ? "启动": "停止");
		Integer count = confSystemMapper.changeSystemStatus(ids, isStartSystem ? 1 : 2, SecurityUtils.getUser().getName());
		if (count == 0) {
			return R.ok("更新失败");
		}
		return R.ok("更新成功");
	}

	/**
	 * 限制配置系统数量
	 * @return boolean
	 */
	private boolean exceedMaxSystemConfigLimit(){
//		String systemLimitMaxEncryptStr = remoteParamService.getByKeyNoInner(RedisKey.SYSTEM_MAX).getData();
//		if (systemLimitMaxEncryptStr == null) {
//			log.error("数据库公共参数表未配置: " + RedisKey.SYSTEM_MAX + "参数");
//			throw new ConfigurationDataException("公共参数表未配置" + RedisKey.SYSTEM_MAX + "参数");
//		}
//		String systemLimitMax = AESUtil.decrypt(systemLimitMaxEncryptStr);
//		return super.count() >= Integer.parseInt(systemLimitMax);
		return false;
	}
}